package com.hedl.practice.diyJava.reflex.dynamic_proxy;

import com.hedl.practice.diyJava.reflex.dynamic_proxy.tmp.Hello;

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;

/**
 * 在运行期动态创建一个interface实例的方法如下：
 *
 *      1.定义一个InvocationHandler实例，它负责实现接口的方法调用；
 *      2.通过Proxy.newProxyInstance()创建interface实例，它需要3个参数：
 *          1.使用的ClassLoader，通常就是接口类的ClassLoader；
 *          2.需要实现的接口数组，至少需要传入一个接口进去；
 *          3.用来处理接口方法调用的InvocationHandler实例。
 *      3.将返回的Object强制转型为接口。
 */
public class StudyDynamicProxy {
    public static void main(String[] args) {

        //动态代理的基本实现
        InvocationHandler handler = new InvocationHandler() {
            @Override
            public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
                System.out.println(method);
                System.out.println(method.getName());       //morning
                if (method.getName().equals("morning")){
                    System.out.println("Good morning,"+args[0]);
                }
                return null;
            }
        };
        Hello hello = (Hello) Proxy.newProxyInstance(
                Hello.class.getClassLoader(),       //传入ClassLoader
                new Class[]{Hello.class},       //传入要实现的接口
                handler);       //传入处理调用方法的InvocationHandler
        hello.morning("Bob");
    }

    //改变成静态实现,先实现接口
    /*InvocationHandler handler;
    public StudyDynamicProxy(InvocationHandler handler){
        this.handler = handler;
    }

    @Override
    public void morning(String name) {
        try {
            handler.invoke(this,Hello.class.getMethod("morning", String.class),new Object[]{name});
        } catch (Throwable e) {
            throw new RuntimeException(e);
        }
    }*/
}
